package com.shuyixiao;

import org.apache.http.HttpResponse;
import org.apache.http.client.methods.CloseableHttpResponse;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.impl.client.HttpClients;
import org.apache.http.util.EntityUtils;
import org.json.JSONArray;
import org.json.JSONObject;

import java.io.IOException;
import java.time.Duration;
import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

/**
 * @author 舒一笑
 * @version 1.0.0
 * @ClassName GitLabDetailedStats.java
 * @Description 代码统计计算
 * @createTime 2023年10月08日 13:49:00
 */
public class GitLabDetailedStats {

    /**
     * 项目ID
     */
    static String projectID = "271";

    /**
     * GitLab Token
     */
    static String privateToken = "glpat-UHm-qN7qpBexdAu1MkXU";

    static DateTimeFormatter formatter = DateTimeFormatter.ISO_DATE_TIME;

    /**
     * 开始时间
     */
    static String since = "2023-07-01T00:00:00Z";

    /**
     * 结束时间，这里使用当前时间
     */
    static String until = LocalDateTime.now().format(formatter);

    static int pageNumber = 1;

    /**
     *  最大值为 100
     */
    static int commitsPerPage = 10000;

    public static void main(String[] args) throws IOException {
        LocalDateTime startTime = LocalDateTime.now();
        CloseableHttpClient httpClient = HttpClients.createDefault();
        HttpGet request = new HttpGet("http://gitlab.hzzcdz.com/api/v4/projects/" + projectID + "/repository/commits?ref_name=hubei-test-0822" + "&since=" + since + "&until=" + until + "&page=" + pageNumber + "&per_page=" + commitsPerPage);
        request.addHeader("PRIVATE-TOKEN", privateToken);
        HttpResponse response = httpClient.execute(request);

        String responseString = EntityUtils.toString(response.getEntity(), "UTF-8");
        JSONArray commitsArray = new JSONArray(responseString);
        // 获取项目成员
        List<Object> list = commitsArray.toList();
        List<Map<String, Object>> commitList = list.stream()
                .map(obj -> (Map<String, Object>) obj)
                .collect(Collectors.toList());
        // 转为List,取出每个commit的author_name
        List<String> members = commitList.stream()
                .map(commit -> (String) commit.get("author_name"))
                .distinct() // 去重
                .collect(Collectors.toList());
        // 获取成员的代码提交次数
        Map<String, Integer> authorCommitCounts = new HashMap<>();
        String authorEmail = null;
        for (int i = 0; i < list.size(); i++) {
            Object authorName = commitList.get(i).get("author_name");
            authorCommitCounts.put((String) authorName, authorCommitCounts.getOrDefault(authorName, 0) + 1);
        }
        // 打印每个人的提交次数
        authorCommitCounts.forEach((author, count) -> System.out.println(author + "的总共提交次数: " + count));
        System.out.println("----------------分割线----------------");
        // 获取项目中代码总共提交情况
        CloseableHttpClient httpClientTotal = HttpClients.createDefault();
        HttpGet requestTotal = new HttpGet("http://gitlab.hzzcdz.com/api/v4/projects/" + projectID + "/repository/commits?ref_name=hubei-test-0822&page=" + pageNumber + "&per_page=" + commitsPerPage);
        requestTotal.addHeader("PRIVATE-TOKEN", privateToken);
        HttpResponse responseTotal = httpClientTotal.execute(requestTotal);
        String responseStringTotal = EntityUtils.toString(responseTotal.getEntity(), "UTF-8");
        JSONArray commitsArrayTotal = new JSONArray(responseStringTotal);
        for (String userName : members) {
            int totalAdditions = 0;
            int totalDeletions = 0;
            for (int i = 0; i < commitsArrayTotal.length(); i++) {
                JSONObject commit = commitsArrayTotal.getJSONObject(i);
                if (!commit.getString("author_name").equals(userName)) {
                    continue;
                }
                String commitSha = commit.getString("id");
                HttpGet diffRequest = new HttpGet("http://gitlab.hzzcdz.com/api/v4/projects/" + "271" + "/repository/commits/" + commitSha + "/diff");
                diffRequest.addHeader("PRIVATE-TOKEN", privateToken);
                CloseableHttpClient client = HttpClients.createDefault();
                CloseableHttpResponse diffResponse = client.execute(diffRequest);

                if (diffResponse.getStatusLine().getStatusCode() != 200) {
                    System.out.println("Failed to get diff: " + diffResponse.getStatusLine().getReasonPhrase());
                    diffResponse.close();
                    continue;
                }

                String diffResponseBody = EntityUtils.toString(diffResponse.getEntity());
                diffResponse.close();

                JSONArray diffs = new JSONArray(diffResponseBody);

                for (int j = 0; j < diffs.length(); j++) {
                    JSONObject diff = diffs.getJSONObject(j);
                    String diffContent = diff.getString("diff");
                    int[] counts = countAdditionsAndDeletions(diffContent);
                    totalAdditions += counts[0];
                    totalDeletions += counts[1];
                }
            }
            System.out.println(userName + "总的代码新增行数: " + totalAdditions);
            System.out.println(userName + "总的代码删除行数: " + totalDeletions);
            System.out.println(userName + "总的贡献代码总行数: " + (totalAdditions-totalDeletions));
        }
        System.out.println("----------------分割线----------------");
        // 获取项目成员的代码提交数量
        for (String userName : members) {
            int totalAdditions = 0;
            int totalDeletions = 0;
            for (int i = 0; i < commitsArray.length(); i++) {
                JSONObject commit = commitsArray.getJSONObject(i);
                if (!commit.getString("author_name").equals(userName)) {
                    continue;
                }
                String commitSha = commit.getString("id");
                HttpGet diffRequest = new HttpGet("http://gitlab.hzzcdz.com/api/v4/projects/" + "271" + "/repository/commits/" + commitSha + "/diff");
                diffRequest.addHeader("PRIVATE-TOKEN", privateToken);
                CloseableHttpClient client = HttpClients.createDefault();
                CloseableHttpResponse diffResponse = client.execute(diffRequest);

                if (diffResponse.getStatusLine().getStatusCode() != 200) {
                    System.out.println("Failed to get diff: " + diffResponse.getStatusLine().getReasonPhrase());
                    diffResponse.close();
                    continue;
                }

                String diffResponseBody = EntityUtils.toString(diffResponse.getEntity());
                diffResponse.close();

                JSONArray diffs = new JSONArray(diffResponseBody);

                for (int j = 0; j < diffs.length(); j++) {
                    JSONObject diff = diffs.getJSONObject(j);
                    String diffContent = diff.getString("diff");
                    int[] counts = countAdditionsAndDeletions(diffContent);
                    totalAdditions += counts[0];
                    totalDeletions += counts[1];
                }
            }
            System.out.println(userName + "该季度的代码新增行数: " + totalAdditions);
            System.out.println(userName + "该季度的代码删除行数: " + totalDeletions);
            System.out.println(userName + "该季度的贡献代码总行数: " + (totalAdditions-totalDeletions));
        }
        LocalDateTime endTime = LocalDateTime.now();
        Duration duration = Duration.between(startTime, endTime);
        long diff = duration.getSeconds(); // Get difference in seconds
        System.out.println("时间花费了: " + diff + " seconds");
    }

    /**
     * 代码行数换算
     * @param diffContent
     * @return
     */
    public static int[] countAdditionsAndDeletions(String diffContent) {
        String[] lines = diffContent.split("\n");
        int additions = 0;
        int deletions = 0;

        for (String line : lines) {
            if (line.startsWith("+") && !line.startsWith("+++")) {
                additions++;
            } else if (line.startsWith("-") && !line.startsWith("---")) {
                deletions++;
            }
        }

        return new int[]{additions, deletions};
    }
}





